#include <Hal/PmBitmap.h>
#include <BootConsole.h>

#define BitsPerEntry (sizeof(uint64_t) * 8)

void PmBitmap::PmReset()
{
	Reset();

	/* First 4096 pages (16MB) are handled by other structures. Set them as used */
	for (size_t i = 0; i < (0x1000000 / 0x1000) / BitsPerEntry; i++)
		Data[i] = 0xFF;
}

uintptr_t PmBitmap::FirstFree(uintptr_t base) const
{
	if (base < 0x1000000)
		throw ArgumentOutOfRangeException("Pages under 16Mb are handled differently");
	
	return FindFirst(base / 0x1000, false);
}

void PmBitmap::SetPage(uintptr_t addr)
{
	if (addr < 0x1000000)
		throw ArgumentOutOfRangeException("Pages under 16Mb are handled differently");

	uint64_t index = addr / 0x1000;
	Set(index);
}

void PmBitmap::ClearPage(uintptr_t addr)
{
	if (addr < 0x1000000)
		throw ArgumentOutOfRangeException("Pages under 16Mb are handled differently");

	uint64_t index = addr / 0x1000;
	Clear(index);
}

bool PmBitmap::TestPage(uintptr_t addr) const
{
	if (addr < 0x1000000)
		throw ArgumentOutOfRangeException("Pages under 16Mb are handled differently");
	
	uint64_t index = addr / 0x1000;
	return Test(index);
}

void PmBitmap::Protect(uintptr_t base, size_t count)
{
	if (base < 0x1000000)
		throw ArgumentOutOfRangeException("Pages under 16Mb are handled differently");
	
	Massive(base / 0x1000, count, true);
}
